﻿using System;
using HslCommunication.Core;

namespace HslCommunication.BasicFramework
{
	/// <summary>
	/// 一个简单的不持久化的序号自增类，采用线程安全实现，并允许指定最大数字，将包含该最大值，到达后清空从指定数开始<br />
	/// A simple non-persistent serial number auto-increment class, which is implemented with thread safety, and allows the maximum number to be specified, which will contain the maximum number, and will be cleared from the specified number upon arrival.
	/// </summary>
	/// <example>
	/// 先来看看一个简单的应用的
	/// <code lang="cs" source="HslCommunication_Net45.Test\Documentation\Samples\BasicFramework\SoftIncrementCountSample.cs" region="Sample1" title="简单示例" />
	/// 再来看看一些复杂的情况
	/// <code lang="cs" source="HslCommunication_Net45.Test\Documentation\Samples\BasicFramework\SoftIncrementCountSample.cs" region="Sample2" title="复杂示例" />
	/// 其他一些特殊的设定
	/// <code lang="cs" source="HslCommunication_Net45.Test\Documentation\Samples\BasicFramework\SoftIncrementCountSample.cs" region="Sample3" title="其他示例" />
	/// </example>
	// Token: 0x02000198 RID: 408
	public sealed class SoftIncrementCount : IDisposable
	{
		/// <summary>
		/// 实例化一个自增信息的对象，包括最大值，初始值，增量值<br />
		/// Instantiate an object with incremental information, including the maximum value and initial value, IncreaseTick
		/// </summary>
		/// <param name="max">数据的最大值，必须指定</param>
		/// <param name="start">数据的起始值，默认为0</param>
		/// <param name="tick">每次的增量值</param>
		// Token: 0x060020EE RID: 8430 RVA: 0x000A0078 File Offset: 0x0009E278
		public SoftIncrementCount(long max, long start = 0L, int tick = 1)
		{
			this.start = start;
			this.max = max;
			this.current = start;
			this.IncreaseTick = tick;
			this.hybirdLock = new SimpleHybirdLock();
		}

		/// <summary>
		/// 获取自增信息，获得数据之后，下一次获取将会自增，如果自增后大于最大值，则会重置为最小值，如果小于最小值，则会重置为最大值。<br />
		/// Get the auto-increment information. After getting the data, the next acquisition will auto-increase. 
		/// If the auto-increment is greater than the maximum value, it will reset to the minimum value.
		/// If the auto-increment is smaller than the minimum value, it will reset to the maximum value.
		/// </summary>
		/// <returns>计数自增后的值</returns>
		// Token: 0x060020EF RID: 8431 RVA: 0x000A00E4 File Offset: 0x0009E2E4
		public long GetCurrentValue()
		{
			this.hybirdLock.Enter();
			long result = this.current;
			this.current += (long)this.IncreaseTick;
			bool flag = this.current > this.max;
			if (flag)
			{
				this.current = this.start;
			}
			else
			{
				bool flag2 = this.current < this.start;
				if (flag2)
				{
					this.current = this.max;
				}
			}
			this.hybirdLock.Leave();
			return result;
		}

		/// <summary>
		/// 重置当前序号的最大值，最大值应该大于初始值，如果当前值大于最大值，则当前值被重置为最大值<br />
		/// Reset the maximum value of the current serial number. The maximum value should be greater than the initial value. 
		/// If the current value is greater than the maximum value, the current value is reset to the maximum value.
		/// </summary>
		/// <param name="max">最大值</param>
		// Token: 0x060020F0 RID: 8432 RVA: 0x000A0170 File Offset: 0x0009E370
		public void ResetMaxValue(long max)
		{
			this.hybirdLock.Enter();
			bool flag = max > this.start;
			if (flag)
			{
				bool flag2 = max < this.current;
				if (flag2)
				{
					this.current = this.start;
				}
				this.max = max;
			}
			this.hybirdLock.Leave();
		}

		/// <summary>
		/// 重置当前序号的初始值，需要小于最大值，如果当前值小于初始值，则当前值被重置为初始值。<br />
		/// To reset the initial value of the current serial number, it must be less than the maximum value. 
		/// If the current value is less than the initial value, the current value is reset to the initial value.
		/// </summary>
		/// <param name="start">初始值</param>
		// Token: 0x060020F1 RID: 8433 RVA: 0x000A01C8 File Offset: 0x0009E3C8
		public void ResetStartValue(long start)
		{
			this.hybirdLock.Enter();
			bool flag = start < this.max;
			if (flag)
			{
				bool flag2 = this.current < start;
				if (flag2)
				{
					this.current = start;
				}
				this.start = start;
			}
			this.hybirdLock.Leave();
		}

		/// <summary>
		/// 将当前的值重置为初始值。<br />
		/// Reset the current value to the initial value.
		/// </summary>
		// Token: 0x060020F2 RID: 8434 RVA: 0x000A0218 File Offset: 0x0009E418
		public void ResetCurrentValue()
		{
			this.hybirdLock.Enter();
			this.current = this.start;
			this.hybirdLock.Leave();
		}

		/// <summary>
		/// 将当前的值重置为指定值，该值不能大于max，如果大于max值，就会自动设置为max<br />
		/// Reset the current value to the specified value. The value cannot be greater than max. If it is greater than max, it will be automatically set to max.
		/// </summary>
		/// <param name="value">指定的数据值</param>
		// Token: 0x060020F3 RID: 8435 RVA: 0x000A0240 File Offset: 0x0009E440
		public void ResetCurrentValue(long value)
		{
			this.hybirdLock.Enter();
			bool flag = value > this.max;
			if (flag)
			{
				this.current = this.max;
			}
			else
			{
				bool flag2 = value < this.start;
				if (flag2)
				{
					this.current = this.start;
				}
				else
				{
					this.current = value;
				}
			}
			this.hybirdLock.Leave();
		}

		/// <summary>
		/// 增加的单元，如果设置为0，就是不增加。如果为小于0，那就是减少，会变成负数的可能。<br />
		/// Increased units, if set to 0, do not increase. If it is less than 0, it is a decrease and it may become a negative number.
		/// </summary>
		// Token: 0x170006B9 RID: 1721
		// (get) Token: 0x060020F4 RID: 8436 RVA: 0x000A02A9 File Offset: 0x0009E4A9
		// (set) Token: 0x060020F5 RID: 8437 RVA: 0x000A02B1 File Offset: 0x0009E4B1
		public int IncreaseTick { get; set; } = 1;

		/// <summary>
		/// 获取当前的计数器的最大的设置值。<br />
		/// Get the maximum setting value of the current counter.
		/// </summary>
		// Token: 0x170006BA RID: 1722
		// (get) Token: 0x060020F6 RID: 8438 RVA: 0x000A02BA File Offset: 0x0009E4BA
		public long MaxValue
		{
			get
			{
				return this.max;
			}
		}

		/// <inheritdoc />
		// Token: 0x060020F7 RID: 8439 RVA: 0x000A02C2 File Offset: 0x0009E4C2
		public override string ToString()
		{
			return string.Format("SoftIncrementCount[{0}]", this.current);
		}

		// Token: 0x060020F8 RID: 8440 RVA: 0x000A02DC File Offset: 0x0009E4DC
		private void Dispose(bool disposing)
		{
			bool flag = !this.disposedValue;
			if (flag)
			{
				if (disposing)
				{
					this.hybirdLock.Dispose();
				}
				this.disposedValue = true;
			}
		}

		/// <inheritdoc cref="M:System.IDisposable.Dispose" />
		// Token: 0x060020F9 RID: 8441 RVA: 0x000A0313 File Offset: 0x0009E513
		public void Dispose()
		{
			this.Dispose(true);
		}

		// Token: 0x040007D2 RID: 2002
		private long start = 0L;

		// Token: 0x040007D3 RID: 2003
		private long current = 0L;

		// Token: 0x040007D4 RID: 2004
		private long max = long.MaxValue;

		// Token: 0x040007D5 RID: 2005
		private SimpleHybirdLock hybirdLock;

		// Token: 0x040007D7 RID: 2007
		private bool disposedValue = false;
	}
}
